/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = frlist.h                                           */
/*  NOTE      =                                                    */
/*  DATE      = 2014/09/29 by yaohl                                */
/*******************************************************************/

#ifndef __FRLIST_H_
#define __FRLIST_H_

/* 节点 */
typedef struct __st_listnode {
    struct __st_listnode  *pre;
    struct __st_listnode  *next;
    void                  *data;
    
    unsigned long  ul_idx;      //普通链表时不用，保存当前节点在hash中的位置
    long           l_key;       //普通链表时不用，hash key
    char *p_key;                //普通链表时不用，hash key(string)
    unsigned int   ui_key_len;  //普通链表时不用，hash key的长度
} Frlist_node;

/* 头节点 */
typedef struct __st_list {
    unsigned int   size;    /* 节点个数 */
    Frlist_node    *head;
    Frlist_node    *tail;
} Frlist_header;

/* list_destroy() 调用改函数，如果为NULL，则不调用 */
typedef void(*list_node_free)(Frlist_node* node);
/* 例子
void my_list_node_free(Frlist_node *node)
{
    free(node->data);
}
*/

/* 获取首节点(参数是Frlist_header) */
#define FRLIST_FIRST_NODE(hdr)      ((hdr)->head)
/* 获取首节点(参数是Frlist_header) */
#define FRLIST_LAST_NODE(hdr)       ((hdr)->tail)
//#define FRLIST_FIRST_NODE(hdr)    ((hdr)?(hdr)->head:NULL)
/* 获取下一个节点(参数是node) */
#define FRLIST_NEXT_NODE(n)     ((n)?(n)->next:NULL)

/* 获取节点数据 (参数是node) */
#define FRLIST_GET_NODE_DATA(n) (n?(n)->data:NULL)
/* 获取节点数据 (参数是Frlist_header) */
#define FRLIST_GET_FISRT_NODE_DATA(hdr) FRLIST_GET_NODE_DATA(FRLIST_FIRST_NODE(hdr))

//比较函数指针 (返回值 <=0; 终止运行)
typedef int(*list_node_compare)(Frlist_node* node_add, Frlist_node* node);
//显示函数指针
typedef void(*list_node_show)(Frlist_node* node, char *p_outbuff, unsigned int ui_buff_size);
//显示全部函数指针
typedef void(*list_node_show_all)(Frlist_node* node, char **pp_outbuff);
//查询函数指针 (比较一致返回0:终止运行;其他返回1)
typedef int(*list_node_find)(Frlist_node* node, const void *p_compare_data);
//运行函数指针 (返回值为0时, 终止运行)
typedef int(*list_node_run)(Frlist_node* node, const void *p_data);


Frlist_header* frlist_create(void);
void frlist_header_init(Frlist_header *p_st_hdr);
unsigned int frlist_size(const Frlist_header* p_st_header);

Frlist_node* frlist_node_create(void* p_data);
//Frlist_node* frlist2_node_create(void* p_data, unsigned long  ul_idx, unsigned char *p_key, unsigned int ui_key_len);
int frlist_empty(Frlist_header *p_st_header);

void frlist_add_tail(Frlist_header *p_st_header, Frlist_node *p_node);
#define frlist_push(x, y) frlist_add_tail(x, y)
void frlist_add_header(Frlist_header *p_st_header, Frlist_node *p_node_add);
void frlist_merge_header(Frlist_header *p_st_hdr_dst, Frlist_header *p_st_hdr_src);
void frlist_add_sort(Frlist_header *p_st_header, Frlist_node *p_node_add, list_node_compare pf_compare);

void frlist_show(Frlist_header *p_st_header, char *p_outbuff, unsigned int ui_buff_size, list_node_show pf_show);
void frlist_show_all(Frlist_header *p_st_header, char **pp_outbuff, list_node_show_all pf_show);
void frlist_show_all2(Frlist_header *p_st_header, char **pp_outbuff, list_node_show pf_show);
int  frlist_run(Frlist_header *p_st_header, void *p_data, list_node_run pf_run);
int frlist_shallow_copy(Frlist_header *p_st_hdr_dst, Frlist_header *p_st_hdr_src);

Frlist_node* frlist_node_idx(const Frlist_header* p_st_header, int i_idx);
Frlist_node *frlist_find(Frlist_header *p_st_header, const void *p_data, list_node_find pf_find);

Frlist_node* frlist_remove_head(Frlist_header *p_st_header);
#define frlist_pop(x) frlist_remove_head(x)

void frlist_remove_from_idx(Frlist_header *p_st_header, int i_idx, list_node_free pf_free);
void frlist_remove_all(Frlist_header *p_st_header, list_node_free pf_free);
void frlist_node_free(Frlist_header *p_st_header, Frlist_node *p_node, int i_del_list, list_node_free pf_free);
void frlist_node_apart(Frlist_header *p_st_header, Frlist_node *p_st_node);
void frlist_destroy(Frlist_header *p_st_header, list_node_free pf_free);

void frlist_node_data_free(Frlist_node *p_st_node);

#endif

